<template>
  <el-drawer v-model="drawerVisible" :destroy-on-close="true" size="450px" :title="`${drawerProps.title}菜单`">
    <el-form
      ref="ruleFormRef"
      label-width="100px"
      label-suffix=" :"
      :rules="rules"
      :disabled="drawerProps.isView"
      :model="drawerProps.row"
      :hide-required-asterisk="drawerProps.isView"
    >
      <el-form-item label="上级菜单" prop="parentId">
        <el-tree-select
          v-model="drawerProps.row.parentId"
          :data="menuList"
          :props="menuTreeSelectProps"
          filterable
          check-strictly
          node-key="menuId"
        >
          <template #default="{ data: { menuName, children } }">
            {{ menuName }}<span v-show="children.length > 0">({{ children.length }})</span></template
          >
        </el-tree-select>
      </el-form-item>

      <el-form-item label="菜单类型">
        <el-radio-group v-model="drawerProps.row.menuType" @change="menuTypeChange">
          <el-radio label="C">菜单</el-radio>
          <el-radio label="F">按钮</el-radio>
        </el-radio-group>
      </el-form-item>

      <el-form-item label="菜单图标" v-if="isMenuShow">
        <SelectIcon v-model:icon-value="drawerProps.row.icon" />
      </el-form-item>

      <el-form-item label="菜单名称" prop="menuName">
        <el-input v-model="drawerProps.row.menuName" clearable></el-input>
      </el-form-item>

      <el-form-item label="显示顺序" prop="menuSort">
        <el-input-number v-model="drawerProps.row.menuSort" :min="1"></el-input-number>
      </el-form-item>

      <el-form-item prop="permission">
        <template #label>
          权限标识
          <el-tooltip
            class="box-item"
            effect="dark"
            content="控制器中定义的权限字符，如：@MarkPermission(value = 'system.menu.add')"
            placement="top"
          >
            <div class="el-icon-inline-block">
              <el-icon><QuestionFilled /></el-icon>
            </div>
          </el-tooltip>
        </template>
        <el-input v-model="drawerProps.row.permission" clearable></el-input>
      </el-form-item>

      <el-form-item label="路由名称" prop="name" v-if="isMenuShow">
        <el-input v-model="drawerProps.row.name" clearable></el-input>
      </el-form-item>

      <el-form-item prop="path" v-if="isMenuShow">
        <template #label>
          路由地址
          <el-tooltip class="box-item" effect="dark" content="路由访问路径" placement="top">
            <div class="el-icon-inline-block">
              <el-icon><QuestionFilled /></el-icon>
            </div>
          </el-tooltip>
        </template>
        <el-input v-model="drawerProps.row.path" clearable></el-input>
      </el-form-item>

      <el-form-item prop="component" v-if="isMenuShow">
        <template #label>
          路由路径
          <el-tooltip
            class="box-item"
            effect="dark"
            content="路由 name (对应页面组件 name, 可用作 KeepAlive 缓存标识 && 按钮权限筛选)"
            placement="top"
          >
            <div class="el-icon-inline-block">
              <el-icon><QuestionFilled /></el-icon>
            </div>
          </el-tooltip>
        </template>
        <el-input v-model="drawerProps.row.component" clearable></el-input>
      </el-form-item>

      <el-form-item prop="activeMenu" v-if="isMenuShow">
        <template #label>
          活动路由
          <el-tooltip
            class="box-item"
            effect="dark"
            content="在菜单中需要高亮的 path (通常用作详情页高亮父级菜单)"
            placement="top"
          >
            <div class="el-icon-inline-block">
              <el-icon><QuestionFilled /></el-icon>
            </div>
          </el-tooltip>
        </template>
        <el-input v-model="drawerProps.row.activeMenu" clearable></el-input>
      </el-form-item>

      <el-form-item prop="redirect" v-if="isMenuShow">
        <template #label>
          路由重定向
          <el-tooltip class="box-item" effect="dark" content="路由重定向地址" placement="top">
            <div class="el-icon-inline-block">
              <el-icon><QuestionFilled /></el-icon>
            </div>
          </el-tooltip>
        </template>
        <el-input v-model="drawerProps.row.redirect" clearable></el-input>
      </el-form-item>

      <el-form-item prop="isLink" v-if="isMenuShow">
        <template #label>
          路由外链
          <el-tooltip class="box-item" effect="dark" content="路由外链时填写的访问地址" placement="top">
            <div class="el-icon-inline-block">
              <el-icon><QuestionFilled /></el-icon>
            </div>
          </el-tooltip>
        </template>
        <el-input v-model="drawerProps.row.isLink" clearable></el-input>
      </el-form-item>

      <el-form-item prop="visible" v-if="isMenuShow">
        <template #label>
          显示状态
          <el-tooltip class="box-item" effect="dark" content="选择隐藏则路由将不会出现在侧边栏，但仍然可以访问" placement="top">
            <div class="el-icon-inline-block">
              <el-icon><QuestionFilled /></el-icon>
            </div>
          </el-tooltip>
        </template>
        <el-radio-group v-model="drawerProps.row.visible" @change="console.log(drawerProps.row.visible)">
          <el-radio :label="1">显示</el-radio>
          <el-radio :label="0">隐藏</el-radio>
        </el-radio-group>
      </el-form-item>

      <el-form-item prop="status">
        <template #label>
          菜单状态
          <el-tooltip class="box-item" effect="dark" content="选择禁用则路由将不会出现在侧边栏，也不能被访问" placement="top">
            <div class="el-icon-inline-block">
              <el-icon><QuestionFilled /></el-icon>
            </div>
          </el-tooltip>
        </template>
        <el-radio-group v-model="drawerProps.row.status">
          <el-radio :label="1">正常</el-radio>
          <el-radio :label="0">禁用</el-radio>
        </el-radio-group>
      </el-form-item>

      <el-form-item prop="isAffix" v-if="isMenuShow">
        <template #label>
          固定标签
          <el-tooltip class="box-item" effect="dark" content="菜单是否固定在标签页中 (首页通常是固定项)" placement="top">
            <div class="el-icon-inline-block">
              <el-icon><QuestionFilled /></el-icon>
            </div>
          </el-tooltip>
        </template>
        <el-radio-group v-model="drawerProps.row.isAffix">
          <el-radio :label="1">固定</el-radio>
          <el-radio :label="0">取消</el-radio>
        </el-radio-group>
      </el-form-item>

      <el-form-item prop="isKeepAlive" v-if="isMenuShow">
        <template #label>
          路由缓存
          <el-tooltip class="box-item" effect="dark" content="当前路由是否缓存" placement="top">
            <div class="el-icon-inline-block">
              <el-icon><QuestionFilled /></el-icon>
            </div>
          </el-tooltip>
        </template>
        <el-radio-group v-model="drawerProps.row.isKeepAlive">
          <el-radio :label="1">缓存</el-radio>
          <el-radio :label="0">取消</el-radio>
        </el-radio-group>
      </el-form-item>
    </el-form>

    <template #footer>
      <el-button @click="drawerVisible = false">取消</el-button>
      <el-button type="primary" v-show="!drawerProps.isView" @click="handleSubmit">确定</el-button>
    </template>
  </el-drawer>
</template>

<script setup lang="ts" name="MenuDrawer">
import { ref, reactive } from "vue";
import { ElMessage, FormInstance } from "element-plus";
import { Menu } from "@/api/interface/systemMenu";
import SelectIcon from "@/components/SelectIcon/index.vue";
import { getMenuListApi, getMenuDetailApi } from "@/api/modules/menu";
import { menuTreeHandle } from "@/utils/index";

const menuTreeSelectProps = {
  label: "menuName"
};

const rules = reactive({
  menuName: [{ required: true, message: "请填写菜单名称" }],
  menuSort: [{ required: true, message: "请填写显示顺序" }],
  name: [{ required: true, message: "请填写路由名称" }],
  path: [{ required: true, message: "请填写路由地址" }]
});

// 树形菜单
const menuList = ref<Menu.MenuListRes[]>([]);

interface DrawerProps {
  title: string;
  isView: boolean;
  row: Partial<Menu.MenuDetailRes>;
  api?: (params: any) => Promise<any>;
  getTableList?: () => void;
  menuId?: number;
  parentId?: number;
}

const drawerVisible = ref(false);
const isMenuShow = ref<Boolean>(true);
const drawerProps = ref<DrawerProps>({
  isView: false,
  title: "",
  row: {}
});

// 主栏目菜单
const defaultMenu: Menu.MenuListRes = {
  menuId: 0,
  parentId: 0,
  menuName: "主栏目",
  menuSort: 1,
  menuType: "C",
  visible: 1,
  status: 1,
  permission: "",
  remark: "",
  name: "",
  path: "",
  component: "",
  icon: "",
  createTime: "",
  children: []
};
// 获取菜单列表
const getMenuList = async () => {
  return getMenuListApi().then(res => {
    const { data } = res;
    if (data.length > 0) {
      menuList.value = [...[defaultMenu], ...menuTreeHandle(data, data[0].parentId)];
    } else {
      menuList.value = [];
    }
  });
};

// 获取菜单详情
const getMenuDetail = async (menuId: number) => {
  const { data } = await getMenuDetailApi(menuId);
  drawerProps.value.row = data;
};

// 接收父组件传过来的参数
const acceptParams = async (params: DrawerProps) => {
  drawerProps.value = params;

  // 获取菜单列表
  await getMenuList();

  // 获取菜单详情
  if (undefined != params.menuId && params.menuId > 0) {
    await getMenuDetail(params.menuId);
  }

  if (params.title == "新增") {
    drawerProps.value.row = {
      menuId: 0,
      parentId: 0,
      menuName: "",
      menuSort: 1,
      menuType: "C",
      visible: 1,
      status: 1,
      permission: "",
      remark: "",
      name: "",
      path: "",
      component: "",
      icon: "",
      activeMenu: "",
      redirect: "",
      isLink: "",
      isAffix: 0,
      isKeepAlive: 1
    };
    if (undefined != params.parentId && params.parentId > 0) {
      drawerProps.value.row.parentId = params.parentId;
    }
  }

  menuTypeChange();
  drawerVisible.value = true;
};

// 提交数据（新增/编辑）
const ruleFormRef = ref<FormInstance>();
const handleSubmit = () => {
  ruleFormRef.value!.validate(async valid => {
    if (!valid) return;
    try {
      await drawerProps.value.api!(drawerProps.value.row);
      ElMessage.success({ message: `${drawerProps.value.title}菜单成功！` });
      drawerProps.value.getTableList!();
      drawerVisible.value = false;
    } catch (error) {
      console.log(error);
    }
  });
};

const menuTypeChange = () => {
  isMenuShow.value = drawerProps.value.row.menuType == "C";
};

defineExpose({
  acceptParams
});
</script>
<style scoped>
.el-icon-inline-block {
  display: inline-block;
}
</style>
